package com.library.xtype;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import android.content.Context;
import android.util.SparseArray;

/**
 * Created by jiangtao on 16/5/21.
 *
 * @author jiang.tao
 * @version 1.0.0
 */
final class ItemViewFactoryDefault implements ItemViewFactory {

    private NuwaItemPool mItemViewManager;

    private final SparseArray<Constructor<? extends INuwaItemBinder>> STRING_CONSTRUCTOR_HASH_MAP =
            new SparseArray<>();
    private final SparseArray<Constructor<? extends INuwaItemBinder>> DDEFAULT_STRING_CONSTRUCTOR_HASH_MAP =
            new SparseArray<>();

    private Class<?>[] M_CONSTRUCTOR_SIGNATURE = new Class[]{Context.class};

    private Object[] mConstructorArgs = new Object[1];

    public void destory() {
        mConstructorArgs = null;
        M_CONSTRUCTOR_SIGNATURE = null;
        DDEFAULT_STRING_CONSTRUCTOR_HASH_MAP.clear();
        STRING_CONSTRUCTOR_HASH_MAP.clear();
    }

    /**
     * ItemViewFactory
     *
     * @param itemViewManager itemViewRepository
     */
    public ItemViewFactoryDefault(NuwaItemPool itemViewManager) {
        mItemViewManager = itemViewManager;
    }

    /**
     * create item view
     *
     * @param itemType item view object
     * @return item view
     */
    @Override
    public INuwaItemBinder createItemView(Context context, int itemType) {
        INuwaItemBinder itemView = null;

        Constructor<? extends INuwaItemBinder> constructor = STRING_CONSTRUCTOR_HASH_MAP.get(itemType);

        // get constructor of item view
        if (constructor == null) {
            try {
                Class<? extends INuwaItemBinder> clazz = mItemViewManager.getItemBinder(itemType);

                constructor = clazz.getConstructor(M_CONSTRUCTOR_SIGNATURE);
                STRING_CONSTRUCTOR_HASH_MAP.put(itemType, constructor);
            } catch (NoSuchMethodException e) {
//                e.printStackTrace();
            }
        }

        if (constructor != null) {
            try {
                mConstructorArgs[0] = context;
                Object[] args = mConstructorArgs;
                constructor.setAccessible(true);
                itemView = constructor.newInstance(args);
                mConstructorArgs[0] = null;
                return itemView;
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }

        constructor = DDEFAULT_STRING_CONSTRUCTOR_HASH_MAP.get(itemType);
        // new instance of item view
        if (constructor == null && itemView == null) {
            try {
                Class<? extends INuwaItemBinder> clazz = mItemViewManager.getItemBinder(itemType);
                constructor = clazz.getConstructor();
                DDEFAULT_STRING_CONSTRUCTOR_HASH_MAP.put(itemType, constructor);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }

        if (constructor != null && itemView == null) {
            try {
                constructor.setAccessible(true);
                itemView = constructor.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }

        }

        return itemView;
    }
}
